package plp.orientadaObjetos2.declaracao.funcao;

import plp.expressions2.memory.VariavelJaDeclaradaException;
import plp.expressions2.memory.VariavelNaoDeclaradaException;
import plp.orientadaObjetos1.declaracao.procedimento.ListaDeclaracaoParametro;
import plp.orientadaObjetos1.excecao.declaracao.ClasseJaDeclaradaException;
import plp.orientadaObjetos1.excecao.declaracao.ClasseNaoDeclaradaException;
import plp.orientadaObjetos1.excecao.declaracao.ProcedimentoJaDeclaradoException;
import plp.orientadaObjetos1.excecao.declaracao.ProcedimentoNaoDeclaradoException;
import plp.orientadaObjetos1.expressao.leftExpression.Id;
import plp.orientadaObjetos1.memoria.AmbienteCompilacaoOO1;
import plp.orientadaObjetos1.util.Tipo;
import plp.orientadaObjetos2.memoria.AmbienteCompilacaoOO2;
import plp.orientadaObjetos2.memoria.FuncaoJaDeclaradaException;

public class DecFuncaoNativa implements DecFuncao {

	/**
	 * Identificador do tipo de retorn desta funcao.
	 */
	protected Tipo tipoRetorno;
	
	/**
     * Identificador do funcao.
     */
    protected Id nome;

    /**
     * Parametros declarados para esta funcao.
     */
    protected ListaDeclaracaoParametro parametrosFormais;

    protected boolean hasVarargs;

	public DecFuncaoNativa(Tipo tipoRetorno, Id nome,
			ListaDeclaracaoParametro parametrosFormais, boolean hasVarargs) {
		super();
		this.tipoRetorno = tipoRetorno;
		this.nome = nome;
		this.parametrosFormais = parametrosFormais;
		this.hasVarargs = hasVarargs;
	}

	public Tipo getTipoRetorno() {
		return tipoRetorno;
	}

	public Id getNome() {
		return nome;
	}

	public ListaDeclaracaoParametro getParametrosFormais() {
		return parametrosFormais;
	}

	public boolean hasVarargs() {
		return hasVarargs;
	}

	@Override
	public boolean checaTipo(AmbienteCompilacaoOO1 ambiente)
			throws VariavelJaDeclaradaException, VariavelNaoDeclaradaException,
			ProcedimentoJaDeclaradoException,
			ProcedimentoNaoDeclaradoException, ClasseJaDeclaradaException,
			ClasseNaoDeclaradaException, FuncaoJaDeclaradaException {
		boolean tipoOk = this.parametrosFormais.checaTipo(ambiente) && this.tipoRetorno.eValido(ambiente);
		((AmbienteCompilacaoOO2)ambiente).mapFuncao(this.nome, this);
        return tipoOk;
	}

}
